package com.glp.work.flow.listener;

import com.glp.work.flow.config.apollo.ApplicationValue;
import com.glp.work.flow.constant.MessageTypeEnum;
import com.glp.work.flow.constant.OrderStatus;
import com.glp.work.flow.pojo.WfOrder;
import com.glp.work.flow.request.ProcessStatusRequest;
import com.glp.work.flow.service.OrderInfoService;
import com.glp.work.flow.service.SyncProcessStatusService;
import com.glp.work.flow.utils.SpringUtil;
import com.glp.work.flow.workflow.plugin.flowable.constant.FlowConstant;
import lombok.extern.slf4j.Slf4j;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author pengjia
 * @version 2020年6月5日 上午11:05:25
 */
@Component
@Slf4j
public class MiddleMessageHandler implements ExecutionListener {

    private static final long serialVersionUID = 8315259229279629103L;

    public static final String MIDDEL_MESSAGE_LISTENER_IMPL = "com.glp.work.flow.listener.MiddleMessageHandler";

    private static OrderInfoService orderInfoService;

    private static SyncProcessStatusService syncProcessStatusService;

    private static RepositoryService repositoryService;

    @Override
    public void notify(DelegateExecution execution) {

        log.info("【中间消息】【执行监听器】Event={}", execution.getEventName());
        if (GlobalExecutionHandler.EVENTNAME_START.equals(execution.getEventName())) {
            startHandler(execution);
        } else if (GlobalExecutionHandler.EVENTNAME_TAKE.equals(execution.getEventName())) {
            log.info("MiddleMessageHandler 暂无处理逻辑");
        } else if (GlobalExecutionHandler.EVENTNAME_END.equals(execution.getEventName())) {
            endHandler(execution);
        }
    }

    private void startHandler(DelegateExecution execution) {
        log.info("中间消息节点发送mq消息：start");
        String processInstanceId = execution.getProcessInstanceId();
        String processDefinitionId = execution.getProcessDefinitionId();
        String procDefKey = repositoryService.createProcessDefinitionQuery().processDefinitionId(execution.getProcessDefinitionId()).active().singleResult().getKey();
        Map<String, Object> transientVariables = execution.getTransientVariables();
        List<String> porcKeyList = getPorcKeyList();
        if (!porcKeyList.contains(procDefKey)) {
            log.info("中间消息开始发送mq消息");
            ProcessStatusRequest request = new ProcessStatusRequest();
            List<HistoricActivityInstance> histTask = AssignerTaskHandler.getHistTask(processInstanceId);
            if (CollectionUtils.isNotEmpty(histTask)) {
                HistoricActivityInstance historicActivityInstance = histTask.get(0);
                request.setPreviousNode(historicActivityInstance.getActivityName());
            }
            request.setProcessDefKey(procDefKey);
            Map<String, Object> variables = execution.getVariables();
            if (variables != null) {
                if (variables.get(FlowConstant.AUDIT_PASS) != null) {
                    request.setOperation(execution.getVariables().get(FlowConstant.AUDIT_PASS).toString());
                }
            }
            String createUser = null;
            Object submitter = execution.getVariables().get(FlowConstant.SUBMITTER);
            if (submitter != null) {
                createUser = submitter.toString();
            }
            request.setOrderId(execution.getProcessInstanceBusinessKey());
            request.setProcessId(processInstanceId);
            request.setCurrentNode(((ExecutionEntityImpl) execution).getActivityName());
            request.setLogo(FlowConstant.BEGIN);
            request.setMessageType(MessageTypeEnum.INTERMEDIATE_CATCH_EVENT.getType());
            request.setSubmitUser(createUser);
            request.setTaskDefId(execution.getCurrentActivityId());
            request.setProcessDefId(processDefinitionId);
            syncProcessStatusService.syncProcessStatus((String) transientVariables.get(FlowConstant.APPID), request);
        }
    }

    private void endHandler(DelegateExecution execution) {
        String processId = execution.getProcessInstanceId();
        log.info("【中间消息】更新工单状态为：待审核！processId={}", processId);
        WfOrder record = new WfOrder();
        record.setOrderStatus(OrderStatus.PROCESSING.getCode());
        orderInfoService.updateWfOrder(processId, record);
    }

    private List<String> getPorcKeyList() {
        ApplicationValue bean = SpringUtil.getBean(ApplicationValue.class);
        String apolloValue = bean.getApolloValue("hot.procDefKey");
        log.info("监听器获取apollo的值:{}", apolloValue);
        List<String> split;
        split = Arrays.asList(apolloValue.split(","));
        return split;
    }

    @Autowired
    public void setOrderInfoService(OrderInfoService orderInfoService) {
        MiddleMessageHandler.orderInfoService = orderInfoService;
    }


    @Autowired
    public void setSyncProcessStatusService(SyncProcessStatusService syncProcessStatusService) {
        MiddleMessageHandler.syncProcessStatusService = syncProcessStatusService;
    }

    @Autowired
    public void setRepositoryService(RepositoryService repositoryService) {
        MiddleMessageHandler.repositoryService = repositoryService;
    }
}
